package com.weicai.hive.udf;

import java.io.UnsupportedEncodingException;

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

import com.weicai.caesar.CaesarUtil;
import com.weicai.hive.util.StringPadUtil;

public class NFCSReportUDF extends UDF {

    public Text evaluate(String... arr) throws UnsupportedEncodingException {
        Text text = new Text();
        if (arr[0].equals("user")) {
            text.set(userBaseInfo(arr));
        } else if (arr[0].equals("lend")) {
            text.set(lendinfo(arr));
        } else if (arr[0].equals("loan")) {
            text.set(loanInfo(arr));
        } else if (arr[0].equals("special")) {
            text.set(specialInfo(arr));
        } else if(arr[0].equals("delete")){
        	text.set(deleteInfo(arr));
        } else {
            System.out.println("未找到匹配的参数！！！！！！！！！！");
            throw new RuntimeException(
                "第一个参数，必须在('user','lend','loan','special')中");
        }

        return text;

    }

    private String userBaseInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        sb.append("P").append(arr[1]);
        //姓名
        sb.append(StringPadUtil.rightPad(decode(arr[2]), 30));
        //证件类型
        sb.append(arr[3]);
        //证件号码
        sb.append(StringPadUtil.rightPad(decode(arr[4]), 18));
        //信息类别
        sb.append("B");
        //性别
        sb.append(StringPadUtil.leftPad(arr[5], 1));
        //出生日期
        if (arr[6] == null) {
            arr[6] = "19010101";
        }
        sb.append(StringPadUtil.leftPad(arr[6], 8));
        //婚姻状况
        sb.append(StringPadUtil.leftPad(arr[7], 2));
        //高学历
        sb.append(StringPadUtil.leftPad(arr[8], 2));
        //最高学位
        sb.append(StringPadUtil.leftPad(arr[9], 1));
        //住宅电话
        sb.append(StringPadUtil.rightPad(arr[10], 25));
        //手机号码
        sb.append(StringPadUtil.rightPad(decode(arr[11]), 16));
        //单位电话
        sb.append(StringPadUtil.rightPad(decode(arr[12]), 25));
        //电子邮箱
        sb.append(StringPadUtil.rightPad(arr[13], 30));
        //通讯地址
        sb.append(StringPadUtil.rightPad(arr[14], 60));
        //通讯地址邮政编码
        sb.append(StringPadUtil.rightPad(arr[15], 6));
        //户籍地址
        sb.append(StringPadUtil.rightPad(arr[16], 60));
        //配偶姓名
        sb.append(StringPadUtil.rightPad(decode(arr[17]), 30));
        //配偶证件类型
        sb.append(StringPadUtil.rightPad(arr[18], 1));
        //配偶证件号码
        sb.append(StringPadUtil.rightPad(decode(arr[19]), 18));
        //配偶工作单位
        sb.append(StringPadUtil.rightPad(arr[10], 60));
        //配偶联系电话
        sb.append(StringPadUtil.rightPad(decode(arr[21]), 25));
        //第一联系人姓名
        if (!isLetterDigitOrChinese(decode(arr[22]))) {
            arr[22] = "未知";
        }
        sb.append(StringPadUtil.rightPad(decode(arr[22]), 30));
        //第一联系人关系
        sb.append(StringPadUtil.rightPad(arr[23], 1));
        //第一联系人电话
        sb.append(StringPadUtil.rightPad(decode(arr[24]), 25));
        //第二联系人姓名
        if (!isLetterDigitOrChinese(decode(arr[25]))) {
            arr[25] = "未知";
        }
        sb.append(StringPadUtil.rightPad(decode(arr[25]), 30));
        //第二联系人关系
        sb.append(StringPadUtil.rightPad(arr[26], 1));
        //第二联系人电话
        sb.append(StringPadUtil.rightPad(decode(arr[27]), 25));
        //职业信息类别
        sb.append("C");
        //职业
        sb.append(StringPadUtil.rightPad(arr[28], 1));
        //单位名称
        sb.append(StringPadUtil.rightPad(arr[29], 60));
        //单位所属行业
        sb.append(StringPadUtil.rightPad(arr[30], 1));
        //单位地址
        sb.append(StringPadUtil.rightPad(arr[31], 60));
        //单位地址邮政编码
        sb.append(StringPadUtil.leftPad(arr[32], 6));
        //本单位工作起始年 份
        sb.append(StringPadUtil.leftPad(arr[33], 4));
        //职务
        sb.append(StringPadUtil.leftPad(arr[34], 1));
        //职称
        sb.append(StringPadUtil.leftPad(arr[35], 1));
        //年收入
        sb.append(StringPadUtil.leftPad(arr[36], 10));
        //居住地址段数据项信息类别
        sb.append("D");
        //居住地址
        sb.append(StringPadUtil.rightPad(arr[37], 60));
        //居住地址邮政编码
        sb.append(StringPadUtil.leftPad(arr[38], 6));
        //居住状况
        sb.append(StringPadUtil.rightPad(arr[39], 1));
        return sb.toString();
    }

    /**
     * 处理借款申请数据
     * 
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String lendinfo(String... arr) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //借款申请信息类别，机构代码
        sb.append("S").append(arr[1]);
        //借款申请号
        sb.append(StringPadUtil.rightPad(arr[2], 40));
        //姓名
        sb.append(StringPadUtil.rightPad(decode(arr[3]), 30));
        //证件类型
        sb.append(StringPadUtil.rightPad(arr[4], 1));
        //证件号码
        sb.append(StringPadUtil.rightPad(decode(arr[5]), 18));
        //借款申请类型
        sb.append(StringPadUtil.rightPad(arr[6], 2));
        //借款申请金额
        sb.append(StringPadUtil.leftPad(arr[7], 10));
        //借款申请月数
        sb.append(StringPadUtil.leftPad(arr[8], 6));
        //借款申请时间
        sb.append(StringPadUtil.leftPad(arr[9], 8));
        //借款申请状态
        sb.append(StringPadUtil.rightPad(arr[10], 1));
        return sb.toString();
    }

    private String loanInfo(String... arr) throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //借款申请信息类别，机构代码
        sb.append("A").append(arr[1]);
        //借款类型
        sb.append(StringPadUtil.rightPad(arr[2], 2));
        //借款合同号码
        sb.append(StringPadUtil.rightPad(arr[3], 60));
        //业务号
        sb.append(StringPadUtil.rightPad(arr[4], 40));
        //发生地点
        sb.append(StringPadUtil.leftPad(arr[5], 6));
        //开户日期
        sb.append(StringPadUtil.leftPad(arr[6], 8));
        //到期日期
        sb.append(StringPadUtil.leftPad(arr[7], 8));
        //币种
        sb.append(StringPadUtil.rightPad(arr[8], 3));
        //授信额度
        sb.append(StringPadUtil.leftPad(arr[9], 10));
        //共享授信额度
        sb.append(StringPadUtil.leftPad(arr[10], 10));
        //最大负债额
        sb.append(StringPadUtil.leftPad(arr[11], 10));
        //担保方式
        sb.append(StringPadUtil.leftPad(arr[12], 1));
        //还款频率
        sb.append(StringPadUtil.rightPad(arr[13], 2));
        //还款月数
        sb.append(StringPadUtil.rightPad(arr[14], 3));
        //剩余还款月数
        sb.append(StringPadUtil.rightPad(arr[15], 3));
        //协定还款期数
        sb.append(StringPadUtil.rightPad(arr[16], 3));
        //协定期还款额
        sb.append(StringPadUtil.rightPad(arr[17], 10));
        //结算/应还款日期
        sb.append(StringPadUtil.leftPad(arr[18], 8));
        //最近一次实际还款 日期
        sb.append(StringPadUtil.leftPad(arr[19], 8));
        //本月应还款金额
        sb.append(StringPadUtil.leftPad(arr[20], 10));
        //本月实际还款金额
        sb.append(StringPadUtil.leftPad(arr[21], 10));
        //余额
        sb.append(StringPadUtil.leftPad(arr[22], 10));
        //当前逾期期数
        sb.append(StringPadUtil.leftPad(arr[23], 2));
        //当前逾期总额
        sb.append(StringPadUtil.leftPad(arr[24], 10));
        //逾期 31-60 天未归还借款本金
        sb.append(StringPadUtil.leftPad(arr[25], 10));
        //逾期 61-90 天未归还借款本金
        sb.append(StringPadUtil.leftPad(arr[26], 10));
        //逾期 91-180 天未归还借款本金
        sb.append(StringPadUtil.leftPad(arr[27], 10));
        //逾期 180 天以上未归还借款本金
        sb.append(StringPadUtil.leftPad(arr[28], 10));
        //累计逾期期数
        sb.append(StringPadUtil.leftPad(arr[29], 3));
        //最高逾期期数
        sb.append(StringPadUtil.leftPad(arr[30], 2));
        //五级分类状态
        sb.append(StringPadUtil.leftPad(arr[31], 1));
        //账户状态
        sb.append(StringPadUtil.leftPad(arr[32], 1));
        //24 月（借款）还款状 态
        sb.append(StringPadUtil.rightPad(arr[33], 24));
        //账户拥有者信息提 示
        sb.append(StringPadUtil.leftPad(arr[34], 1));
        //姓名
        sb.append(StringPadUtil.rightPad(decode(arr[35]), 30));
        //证件类型
        sb.append(StringPadUtil.rightPad(arr[36], 1));
        //证件号码
        sb.append(StringPadUtil.rightPad(decode(arr[37]), 18));
        //预留字段
        sb.append(StringPadUtil.rightPad(arr[38], 30));

        return sb.toString();
    }

    /**
     * 特殊交易信息报文
     * 
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String specialInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //信息类别 机构代码
        sb.append("G").append(arr[1]);
        //姓名
        sb.append(StringPadUtil.rightPad(decode(arr[2]), 30));
        //证件类型
        sb.append(StringPadUtil.rightPad(arr[3], 1));
        //证件号码
        sb.append(StringPadUtil.rightPad(decode(arr[4]), 18));
        //业务号
        sb.append(StringPadUtil.rightPad(arr[5], 40));
        //特殊交易类型
        sb.append(StringPadUtil.leftPad(arr[6], 1));
        //发生日期
        sb.append(StringPadUtil.rightPad(arr[7], 8));
        //变更月数
        if(!arr[8].equals("") && Integer.parseInt(arr[8])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[8].substring(1, 2), 3));
        }else{
        	 sb.append(StringPadUtil.leftPad(arr[8], 4));
        }
        //发生金额
        if(!arr[9].equals("") && Double.parseDouble(arr[9])<0 ){
        	sb.append("-").append(StringPadUtil.leftPad(arr[9].substring(1, 2), 9));
        }else{
        	 sb.append(StringPadUtil.leftPad(arr[9], 10));
        }
        //明细信息
        sb.append(StringPadUtil.rightPad(arr[10], 200));
        return sb.toString();
    }
    /**
     * 删除交易信息报文
     * 
     * @param arr
     * @return
     * @throws UnsupportedEncodingException
     */
    private String deleteInfo(String... arr)
            throws UnsupportedEncodingException {
        StringBuilder sb = new StringBuilder();
        //信息类别 机构代码
        sb.append(arr[1]);
        //业务号
        sb.append(StringPadUtil.rightPad(arr[2], 40));
      //起始结算/应还款日期
        sb.append(StringPadUtil.leftPad(arr[3], 8));
        //结束结算/应还款日期
        sb.append(StringPadUtil.leftPad(arr[4], 8));
       
        return sb.toString();
    }
    private static boolean isLetterDigitOrChinese(String str) {
        if(str==null){
            return false;
        }
        String regex = "^[a-z0-9A-Z\u0020\u3000\uff0c\u002c\uff1f\u003f\u0028\u0029\uff08\uff09\u4e00-\u9fa5]+$";
        return str.matches(regex);
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
//        String s = "PQ10151000HRP00玉素甫·阿不力提甫            0652823199202104011B11992021020999                         13779649381                                                            新疆尉梨县古勒巴格乡哈达墩村北路1号                         999999新疆尉犁县古勒巴格乡哈达墩村北路1号                                                                                                                                                               未知                          21327977XXXX              未知                          61327977XXXX              CY无                                                          E                                                            9999991901990000000000D新疆尉梨县古勒巴格乡哈达墩村北路1号                         9999999";
//        String s2 = "PQ10151000HRP00张聪                          0130185199410080015B11994100810999                         18731172773                                                            获鹿镇潭沟街重新店巷14号                                    999999河北省石家庄市鹿泉区获鹿镇潭沟街重新店巷14号                                                                                                                                                      董丹阳                        21593108XXXX              付子轩                        61593112XXXX              CY无                                                          Q                                                            9999991901990000000000D获鹿镇潭沟街重新店巷14号                                    9999999";
//        String s3 = "PQ10151000HRP00罗汝雯                        0440112198810141243B21988101420999                         13719063060                                                            和平街26号402房                                             999999广州市黄埔区和平街26号402房                                                                                                                                                                       梁淑君                        21501307XXXX              罗铭州                        81314372XXXX              CY无                                                          R                                                            9999991901990000000000D和平街26号402房                                             9999999";
//        System.out.println(s.getBytes("GBK").length);
//        System.out.println(s2.getBytes("GBK").length);
//        System.out.println(s3.getBytes("GBK").length);
//        System.out.println(
//            "|" + new String(s.getBytes("GB18030"), 301, 135, "GB18030") + "|");
//        System.out.println("|"
//            + new String(s2.getBytes("GB18030"), 301, 135, "GB18030") + "|");
//
//        System.out.println(isLetterDigitOrChinese(s));
        String[] arr={"","-5"};
        StringBuilder sb = new StringBuilder();
        if(Integer.parseInt(arr[1])<0){
        	sb.append("-").append(StringPadUtil.leftPad(arr[1].substring(1, 2), 3));
        }else{
        	 sb.append(StringPadUtil.leftPad(arr[1], 4));
        }
//        sb.append("-").append(StringPadUtil.leftPad(arr[1].substring(1, 2), 3));
        System.out.println(sb.toString());
        System.out.println(isLetterDigitOrChinese(""));
    }
    /**
     * 检查明文、密文 进行解密
     * @param s
     * @return
     */
    private static String decode(String s){
        if(CaesarUtil.isEncrypted(s)){
            s=CaesarUtil.decode(s);
        }
        return s;
    }
}
